/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2006
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.analysisModel;

import java.util.ArrayList;

import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.pointValues.PointValues;
import br.ufmg.dees.insane.util.pointValues.StringPointValues;

/**
*A class representing a Beam analysis model of a FrameElement.
*
*@author Fonseca, Flavio & Pitangueira, Roque
*@version 1.1
*@since September 2003, modified October 2006
*/
public class Beam extends FrameElmAnalysis {

	private static final long serialVersionUID = 1L;
	
	public Beam() {
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IMatrix d3, IVector n, IMatrix c) {
		IMatrix b = new IMatrix(2,4);
		b.setElement(0,0, d3.getElement(0,0));
		b.setElement(0,1, d3.getElement(1,0));
		b.setElement(0,2, d3.getElement(2,0));
		b.setElement(0,3, d3.getElement(3,0));
		
		b.setElement(1,0, d2.getElement(0,0));
		b.setElement(1,1, d2.getElement(1,0));
		b.setElement(1,2, d2.getElement(2,0));
		b.setElement(1,3, d2.getElement(3,0));
		return b;
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c) {
		//This method should not be used
		//because it is needed the third order shape functions derivates
		//to form the B matrix for a Beam element
		return null;
	}

	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c, IMatrix u) {
		//This method should not be used
		//because it is needed the third order shape functions derivates
		//to form the B matrix for a Beam element
		return null;
	}

	public IMatrix getDualInternalVariableOperator(IMatrix e) {
		//Matrix e must be FrameElement.getPropertiesMatrix()
		IMatrix d = new IMatrix(2,2);
		double ei = e.getElement(1, 0)*e.getElement(6, 0);
		double ga = e.getElement(2, 0)*e.getElement(7, 0);
		d.setElement(0, 0, ei*ei*e.getElement(9, 0)/ga);
		d.setElement(1, 1, ei);
		return d;
	}

	public IMatrix getStateVariableOperator(IMatrix n2, IVector n1, IMatrix c) {
		if (n2 == null) {
			n2 = new IMatrix(4,1);
		}
		
		IMatrix n = new IMatrix(2, 4);
		n.setZero();
		n.setElement(0, 0, n1.getElement(0));
		n.setElement(0, 1, n1.getElement(1));
		n.setElement(0, 2, n1.getElement(2));
		n.setElement(0, 3, n1.getElement(3));
		n.setElement(1, 0, n2.getElement(0, 0));
		n.setElement(1, 1, n2.getElement(1, 0));
		n.setElement(1, 2, n2.getElement(2, 0));
		n.setElement(1, 3, n2.getElement(3, 0));
		return (n);
	}

	public int getNumberOfInternalVariables() {
		return 2;
	}

	public int getNumberOfDualInternalVariables() {
		return 2;
	}

	public String[] getInternalVariablesLabels() {
		String[] Dlabels = {"GAMAy", "Kz"};
        return Dlabels;
	}

	public String[] getDualInternalVariablesLabels() {
		String[] Dlabels = {"Vy", "Mz"};
        return Dlabels;
	}

	public String getLabel() {
		return "Beam";
	}

	public IMatrix getTransformationMatrix(IMatrix dl, IMatrix cN) {
		
		//"Default" transformation matrix
		IMatrix t = new IMatrix (4, 4);
		t.setIdentity();
		
		return t;
	}

	public ArrayList getDOFLabels(int n) {
		ArrayList <PointValues> al = new ArrayList<PointValues>();
		PointValues spv = new StringPointValues();
	    spv.addPointValue("Dy");
	    spv.addPointValue("Rz");
		for(int i=0; i<n; i++) {
			al.add(i,spv);
		}
		return al;
	}

	@Override
	public IMatrix getLocalStiffnessMatrix(double[] properties) {
		IMatrix mat = new IMatrix(4,4);
		mat.setZero();
		
		double l = properties [0];
		double e = properties[1];
		double g = properties[2];
		double iz = properties[6];
		double a = properties[7];
		double fy = properties[9];
		
		//Setting the value of ei = (E*Iz)
		double ei = e * iz;
		//Setting the value of gy = 6*fy*ei/(g*a*l)
		double gy = 6*fy*ei/(g*a*l);
		//Setting the value of the factor = ei / (1+2*gy)
		double factor = ei / (1+2*gy);
		//Setting the value of l3 = l^3 and l2 = l^2
		double l3 = Math.pow(l, 3);
		double l2 = Math.pow(l, 2);
		
		//Setting the initial value of the upper triangular matrix
		mat.setElement(0, 0, 12.0/l3);
		mat.setElement(0, 1, 6.0/l2);
		mat.setElement(0, 2, -12.0/l3);
		mat.setElement(0, 3, 6.0/l2);
		mat.setElement(1, 1, 4.0/l*(1+2*gy));
		mat.setElement(1, 2, -6.0/l2);
		mat.setElement(1, 3, 2/l*(1-gy));
		mat.setElement(2, 2, 12.0/l3);
		mat.setElement(2, 3, -6.0/l2);
		mat.setElement(3, 3, 4.0/l*(1+gy/2));
		
		//Multiplying the matrix by the factor E*Ix/(1+2*gy)
		for (int i=0; i<4; i++)
			for (int j=i; j<4; j++)
				mat.setElement(i, j, factor*mat.getElement(i, j));
		
		//Setting the value of the lower triangular part of the matrix (symmetry)
		for (int i=0; i<4; i++)
			for (int j=0; j<i; j++)
				mat.setElement(i, j, mat.getElement(j, i));
		
		return (mat);
	}

	@Override
	public IMatrix nodalRotationMatrix(double angle1, double angle2) {
		//A Beam element does not accept inclined supports
		IMatrix mat = new IMatrix(4, 4);
		return (mat);
	}

	public ArrayList getDOFLabels() {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getPMatrix() {
		// TODO Auto-generated method stub
		return null;
	}
	
}
